//============================================================================
//	Johns Hopkins University Engineering for Professionals
//	605.467 Computer Graphics and 605.767 Applied Computer Graphics
//	Instructor:	David W. Nesbitt
//
//	Author:  David W. Nesbitt
//	File:    Segment.h
//	Purpose: 3D Line segment class.
//          Student should  include "geometry.h" to get all class definitions
//          included in proper order.
//
//============================================================================

#ifndef __SEGMENT3_H__
#define __SEGMENT3_H__

#include <math.h>
#include <vector>

/**
 * Line segment in 3D
 */
struct LineSegment3
{
   Point3 A;
   Point3 B;

   /**
    * Default constructor.
    */
   LineSegment3(void)
   {
      A.Set(0.0f, 0.0f, 0.0f);
      B.Set(0.0f, 0.0f, 0.0f);
   }

   /**
    * Constructor given 2 points.
    * @param   p1    First point of the segment.
    * @param   p2    Second point of the segment.
    */
   LineSegment3(const Point3& p1, const Point3& p2)
   {
      A = p1;
      B = p2;
   }
      
   /**
    * Finds the distance of a specified point from the line segment 
    * and the closest point on the segement to the specified point.
    * @param   P           Test point.
    * @param   closestPt   (Return) Closest point on the segment to point P.
    * @return  Returns the distance from P to the closest point on
    *          the segment.
    */
   float Distance(const Point3& P, Point3& closestPt) const
   {
		// Student to define
		Vector3 v = B - A;
		Vector3 w = P - A;
		float theta = v.AngleBetween(w);

		float comp = w.Component(v);

		if(comp > 1)
		{
			closestPt.x = B.x;
			closestPt.y = B.y;
			closestPt.z = B.z;
		}
		else if(comp < -1)
		{
			closestPt.x = A.x;
			closestPt.y = A.y;
			closestPt.z = A.z;
		}
		else
		{
			closestPt.x = (B.x - A.x) * comp;
			closestPt.y = (B.y - A.y) * comp;
			closestPt.z = (B.z - A.z) * comp;
		}
		

		return (w.Norm() * sin(theta));
   }
};

#endif
